/*******************************************************************************
* @file            : Dtstruct.c
* @author       : hai
* @version      : V1.0
* @date          : 2016-3-9
* @brief
********************************************************************************/

#include "stdarg.h"
#include "sys.h"


uint8_t GetChkSum_8(uint8_t *dptr, uint8_t len)
{
    
    uint8_t result;	
    
    result = 0;
    for (; len > 0; len--) {
        result += *dptr++;
    }
    return result;
}

void mem_cpy (void* dst, const void* src, int cnt) 
{
	char *d = (char*)dst;
	const char *s = (const char *)src;
	while (cnt--) *d++ = *s++;
}
/* Fill memory */
void mem_set (void* dst, int val, int cnt) 
{
	char *d = (char*)dst;
	while (cnt--) *d++ = (char)val;
}
/* Compare memory to memory */
int mem_cmp (const void* dst, const void* src, int cnt) 
{
	const char *d = (const char *)dst, *s = (const char *)src;
	int r = 0;
	while (cnt-- && (r = *d++ - *s++) == 0) ;
	return r;
}


/*****************************************************************
* FIFO
******************************************************************/
void InitFIFO(FIFO *fifo, INT8U *array, INT16U deepth)
{
    fifo->deepth = deepth;
    fifo->occupy = 0;
    fifo->array = array;
    fifo->limit = array + deepth;
    fifo->wp = fifo->array;
    fifo->rp = fifo->array;
}

void ResetFIFO(FIFO *fifo)
{
    fifo->occupy = 0;
    fifo->rp = fifo->array;
    fifo->wp = fifo->array;
}

BOOLEAN WriteFIFO(FIFO *fifo, INT8U unit)
{
    if (fifo->occupy >= fifo->deepth) {
        //ReadFIFO(fifo); 
         return FALSE;
    }
    
    *fifo->wp++ = unit;
    
    if (fifo->wp >= fifo->limit) fifo->wp = fifo->array;
    
    OS_ENTER_CRITICAL();
    fifo->occupy++;
    OS_EXIT_CRITICAL();
    
    return TRUE;
}

BOOLEAN WriteFIFOs(FIFO *fifo, INT8U *units, INT16U unitsize)
{
    if (unitsize > fifo->deepth - fifo->occupy) return FALSE;
    
    for (; unitsize > 0; unitsize--) {
        *fifo->wp++ = *units++;
        if (fifo->wp >= fifo->limit) fifo->wp = fifo->array;
        
        OS_ENTER_CRITICAL();
        fifo->occupy++;
        OS_EXIT_CRITICAL();
    }
    
    return TRUE;
}

BOOLEAN FIFOEmpty(FIFO *fifo)
{
    if (fifo->occupy == 0) return 1;
    else return 0;
}

BOOLEAN FIFOFull(FIFO *fifo)
{
    if (fifo->occupy == fifo->deepth) return true;
    else return false;
}

INT16U FIFOSpare(FIFO *fifo)
{
    return fifo->deepth - fifo->occupy;
}

BOOLEAN ReadFIFO(FIFO *fifo, INT8U *ch) 
{
        
    if (fifo->occupy == 0) return false;  
    
    *ch = *fifo->rp++;
    if (fifo->rp >= fifo->limit) fifo->rp = fifo->array;
    
    OS_ENTER_CRITICAL();
    fifo->occupy--;
    OS_EXIT_CRITICAL();
    
    return true;
}

BOOLEAN ReadFIFOs(FIFO *fifo, INT8U *pch, INT8U len) 
{
    INT8U i;
        
    if (fifo->occupy < len) return false;  

    for (i=0; i<len; i++){
        *(pch+i) = *fifo->rp++;
        if (fifo->rp >= fifo->limit) fifo->rp = fifo->array;
        
        OS_ENTER_CRITICAL();
        fifo->occupy--;
        OS_EXIT_CRITICAL();        
    }
    
    return true;
}

BOOLEAN LocateFIFO(FIFO *fifo, INT16U offset)
{
     INT16U off;

    if (offset == 0) return true;
    
    if (fifo->occupy >= offset){    
        if ((fifo->rp + offset) < fifo->limit){
            fifo->rp += offset;            
        } else {
            off = fifo->rp + offset - fifo->limit;
            fifo->rp = fifo->array + off;
        }
        
        fifo->occupy -= offset;  
        return true;
    }else{
        return false;
    }
}

BOOLEAN GetSeekFIFO(FIFO *fifo, INT16U offset, INT8U *ch)
{    
    INT32U off;
    
    if (fifo->occupy > offset){    
        if ((fifo->rp + offset) < fifo->limit){
            *ch = *(fifo->rp + offset);            
        } else {
            off = fifo->rp + offset - fifo->limit;
            *ch = *(fifo->array + off);
        }
        return true;
    } else {
        return false;
    }    
}



INT16U FIFOUsed(FIFO *fifo)
{
    return fifo->occupy;
}

